package com.ksvip.next.components.sequence;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import com.ksvip.next.components.sequence.handler.Sequence;
import com.ksvip.next.components.sequence.properties.SingleSequenceConfiguration;
import com.ksvip.next.components.sequence.single.SingleSequence;
import com.ksvip.next.components.sequence.single.dao.SingleSequenceDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class SequenceGenerator {
    private static final Logger               log = LoggerFactory.getLogger(SequenceGenerator.class);
    private final SingleSequenceConfiguration properties;
    private final DataSource                  dataSource;
    private final Set<String>                 sequenceCache;
    private final Map<String, Sequence>       cache;

    public SequenceGenerator(DataSource datasource, SingleSequenceConfiguration properties) {
        this.dataSource = datasource;
        this.properties = properties;
        this.cache = new ConcurrentHashMap<>();
        this.sequenceCache = new HashSet<>();
        if (properties.getSequenceNames() != null) {
            String[] var3 = properties.getSequenceNames();
            int var4 = var3.length;
            for (int var5 = 0; var5 < var4; ++var5) {
                String sequenceName = var3[var5];
                this.sequenceCache.add(sequenceName);
                log.info("Init Sequence {}", sequenceName);
            }
        }

    }

    public synchronized Sequence getSequence(String sequenceName) throws SQLException {
        if (!this.sequenceCache.contains(sequenceName)) {
            throw new IllegalArgumentException(String.format("xdbc.sequence seqName %s 未配置", sequenceName));
        } else {
            Sequence sequence = this.cache.get(sequenceName);
            if (sequence == null) {
                SingleSequenceDao sequenceDao = new SingleSequenceDao();
                sequenceDao.setAdjust(true);
                sequenceDao.setDataSource(this.dataSource);
                sequenceDao.setInnerStep(this.properties.getInnerStep());
                sequenceDao.setRetryTimes(this.properties.getRetryTimes());
                sequenceDao.init(this.properties.getValueName());
                SingleSequence singleSequence = new SingleSequence();
                singleSequence.setName(sequenceName);
                singleSequence.setSequenceDao(sequenceDao);
                this.cache.put(sequenceName, singleSequence);
                log.info("Init Sequence {}", sequenceName);
                sequence = singleSequence;
            }

            return sequence;
        }
    }
}
